#include "RunnableTaskEvent.h"
#include "ThreadPool.h"
#include "RunnableTask.h"
namespace BattleFire
{
    RunnableTaskEvent* RunnableTaskEvent::CreateGraphEvent()
    {
        return new RunnableTaskEvent;
    }
    void RunnableTaskEvent::Wait(ENamedThreads CurrentThreadIfKnown)
    {
        ThreadPool::Get().WaitUntilTaskCompletes(this, CurrentThreadIfKnown);
    }
    void RunnableTaskEvent::DispatchSubsequents(std::vector<RunnableTask*>& NewTasks, ENamedThreads CurrentThreadIfKnown)
    {
        if (EventsToWaitFor.size())
        {
            RunnableTaskEventArray TempEventsToWaitFor;
            std::swap(EventsToWaitFor,TempEventsToWaitFor);

            bool bSpawnGatherTask = true;
            const bool GTestDontCompleteUntilForAlreadyComplete=true;
            if (GTestDontCompleteUntilForAlreadyComplete)
            {
                bSpawnGatherTask = false;
                for (RunnableTaskEventRef& Item : TempEventsToWaitFor)
                {
                    if (!Item->IsComplete())
                    {
                        bSpawnGatherTask = true;
                        break;
                    }
                }
            }

            if (bSpawnGatherTask)
            {
                ENamedThreads LocalThreadToDoGatherOn = ENamedThreads::AnyHiPriThreadHiPriTask;
                LocalThreadToDoGatherOn = ThreadToDoGatherOn;
                TRunnableTask<FNullGraphTask>::CreateTask(RunnableTaskEventRef(this), &TempEventsToWaitFor, CurrentThreadIfKnown).ConstructAndDispatchWhenReady(LocalThreadToDoGatherOn);
                return;
            }
        }

        SubsequentList.PopAllAndClose(NewTasks);
        for (int32 Index = NewTasks.size() - 1; Index >= 0 ; Index--) // reverse the order since PopAll is implicitly backwards
        {
            RunnableTask* NewTask = NewTasks[Index];
            NewTask->ConditionalQueueTask(CurrentThreadIfKnown);
        }
        NewTasks.clear();
    }
}